class_name CardUI

#注意，这里CardUI只需要初始化状态机即可，并不需要开一个线程去实时运行，因为所有的监控回调函数都可以中断触发，无需开一个线程
extends Control

#思考:为什么要把重新父化的信号写在card_ui.gd文件中？
#答:因为其参数是CardUI，写在这里更方便
signal  reparent_requested(which_card_ui: CardUI)

@export var card: Card : set = _set_card
@export var char_stats: CharacterStats : set = _set_char_stats

@onready var panel: Panel = $Panel
@onready var cost: Label = $Cost
@onready var icon: TextureRect = $Icon
#如果没有as,那么$CardStateMachine返回的是node类型
@onready var card_state_machine: Node = $CardStateMachine as CardStateMachine
@onready var drop_point_detector: Area2D = $DropPointDetector
#定义一个Node数组
@onready var targets: Array[Node] = []
@onready var original_index := self.get_index()

var parent: Control
var tween: Tween
const BASE_STYLE_PANEL = preload("res://custom_resources/card_base_style.tres")
const DRAGGING_STYLE_PANEL =preload("res://custom_resources/card_dragging_style.tres")
const HOVER_STYLE_PANEL =preload("res://custom_resources/card_hover_style.tres")
var playable := true : set = _set_playable
var disabled := false

func _set_card(value: Card) -> void:
	if not is_node_ready():
		await ready
	card = value
	cost.text = str(card.cost)
	icon.texture = card.icon

func _set_char_stats(value: CharacterStats) -> void:
	char_stats = value
	char_stats.stats_changed.connect(_on_char_stats_changed)

func _set_playable(value: bool) -> void:
	playable = value
	if not playable:
		cost.add_theme_color_override("font_color", Color.RED)
		icon.modulate = Color(1, 1, 0, 0.5)
	else:
		cost.remove_theme_color_override("font_color")
		icon.modulate = Color(1, 1, 0, 1)
		
func animate_to_position(new_position: Vector2, duration: float) -> void:
	#设置动画的转换效果和缓慢效果
	tween = create_tween().set_trans(Tween.TRANS_CIRC).set_ease(Tween.EASE_OUT)
	#self是当前节点，即CardUI,动画的属性是global_position
	tween.tween_property(self, "global_position", new_position, duration)

#抽象类中初始化，那么每个实例都会被初始化
func _ready() -> void:
	Events.card_aim_started.connect(_on_card_drag_or_aiming_started)
	Events.card_drag_started.connect(_on_card_drag_or_aiming_started)
	Events.card_drag_ended.connect(_on_card_drag_or_aiming_ended)
	Events.card_aim_ended.connect(_on_card_drag_or_aiming_ended)
	card_state_machine.init(self)

#核心要点是这里的四个回调函数是通过 godot本身封装(_input) / 信号(_on_gui_input, _on_mouse_entered, on_mouse_exited) 来调用的
func _input(event: InputEvent) -> void:
	card_state_machine.on_input(event)

#因为这些回调信号都是control控件发出的，所以要去属于control类型的CardUI下找
#同时，思考为什么要把回调函数放到card_ui.gd中？
#答:因为这些回调函数是状态机的函数，而状态机正是用来控制CardUI的状态的，所以要为每一个CardUI来配一个状态机及其回调函数
func _on_gui_input(event: InputEvent) -> void:
	card_state_machine.on_gui_input(event)
	
func _on_mouse_entered() -> void:
	card_state_machine.on_mouse_entered()
	
func _on_mouse_exited() -> void:
	card_state_machine.on_mouse_exited()
	
#处理碰撞的回调函数
func _on_drop_point_detector_area_entered(area: Area2D) -> void:
	if not targets.has(area):
		targets.append(area)

func _on_drop_point_detector_area_exited(area: Area2D) -> void:
	targets.erase(area)

func play() -> void:
	if not card:
		return
	card.play(targets, char_stats)
	queue_free()

func _on_card_drag_or_aiming_started(used_card: CardUI) -> void:
	if used_card == self:
		return
	disabled = true
	
func _on_card_drag_or_aiming_ended(_card: CardUI) -> void:
	disabled = false
	self.playable = char_stats.can_play_card(card)

func _on_char_stats_changed() -> void:
	self.playable = char_stats.can_play_card(card)

